#ifndef TRIANGLE3D_H
#define TRIANGLE3D_H

#ifndef VECTOR3D_H
#include "Vector3D.h"
#endif

class Triangle3D
{
public:
	Triangle3D(void) {}
	Triangle3D(const Vector3D& p1, const Vector3D& p2, const Vector3D& p3) : mPoint1(p1), mPoint2(p2), mPoint3(p3) {}

public:
	inline const Vector3D getNormal()
	{
		return (mPoint2 - mPoint1).crossProduct(mPoint3 - mPoint1);
	}

	inline const bool isFrontFacing(Vector3D& dir)
	{
		Vector3D n = getNormal().normalize();
		float d = n.dotProduct(dir);
		return d <= 0.0f;
	}

	inline Triangle3D operator +  (const Vector2D& rhs) const
	{
		return Triangle3D(mPoint1 + rhs, mPoint2 + rhs, mPoint3 + rhs);
	}
	inline const Triangle3D& operator += (const Vector2D& rhs)
	{
		mPoint1 += rhs;
		mPoint2 += rhs;
		mPoint3 += rhs;
		return *this;
	}
	inline Triangle3D operator -  (const Vector2D& rhs) const
	{
		return Triangle3D(mPoint1 - rhs, mPoint2 - rhs, mPoint3 - rhs);
	}
	inline const Triangle3D& operator -= (const Vector2D& rhs)
	{
		mPoint1 -= rhs;
		mPoint2 -= rhs;
		mPoint3 -= rhs;
		return *this;
	}

	inline const Triangle3D& operator = (const Triangle3D& rhs)
	{
		mPoint1 = rhs.mPoint1;
		mPoint2 = rhs.mPoint2;
		mPoint3 = rhs.mPoint3;
		return *this;
	}
	inline const bool isPointInside(const Vector3D& p) const
	{
		return (isOnTheSameSide(p, mPoint1, mPoint2, mPoint3) &&
				isOnTheSameSide(p, mPoint1, mPoint2, mPoint3) &&
				isOnTheSameSide(p, mPoint1, mPoint2, mPoint3));
	}

private:
	inline const bool isOnTheSameSide(const Vector3D& p1, const Vector3D& p2,
		const Vector3D& a, const Vector3D& b) const
	{
		Vector3D bminusa = b - a;
		Vector3D cp1 = bminusa.crossProduct(p1 - a);
		Vector3D cp2 = bminusa.crossProduct(p2 - a);
		return (cp1.dotProduct(cp2) >= 0.0f);
	}

protected:
	Vector3D mPoint1;
	Vector3D mPoint2;
	Vector3D mPoint3;
};

#endif
